#include <stdio.h>
#include <string.h>
#include <sys/time.h>
// #include <fcntl.h>
// #include <sys/stat.h>
// #include <sys/types.h>
// #include <unistd.h>

#include "filefrag.h"
#include "dma.h"

int main(int argc, char *argv[]){
    if(argc <= 1){
        printf("argment error, file name not provided!\n");
        return 0;
    }

    struct timeval begin, end, getted;

    //modify file and sync
    // FILE* fp = NULL;
    // fp = fopen();

    gettimeofday(&begin, 0);

    struct fiemap_extent* extents; //store extents of file
    unsigned long long filesize;

    //int num_extent = get_extent("/home/nvme/10G.txt",&extents);
    int num_extent = get_extent(argv[1],&extents,&filesize);
    //int num_extent = get_extent("/home/gary/Code/bigfile.txt",&extents,&filesize);

    gettimeofday(&getted, 0);

    printf("num_extent : %d\nfile size:%lld\n",num_extent,filesize);

    //print extent information
    // for(int i=0;i<num_extent;i++){
    //     printf("%d th extent\n\r",i);
    //     printf("\tfe_logical : %llu\n",extents[i].fe_logical);
    //     printf("\tfe_physical : %llu\n",extents[i].fe_physical);
    //     printf("\tfe_length : %llu\n",extents[i].fe_length);
    //     printf("\tfe_flags : %d\n",extents[i].fe_flags);
    // }

    //send to cosmos
    int buf_size = sizeof(struct fiemap_extent)*num_extent + sizeof(unsigned long long) + sizeof(int);
    char* buf_start = (char*)malloc(buf_size);
    memset(buf_start,0,buf_size);

    //copy file size and extent size 
    char* buf_index = buf_start;
    memcpy(buf_index,(char*)(&filesize),sizeof(unsigned long long));
    buf_index += sizeof(unsigned long long);
    memcpy(buf_index,(char*)(&num_extent),sizeof(int));
    buf_index += sizeof(int);

    //copy extents
    memcpy(buf_index,(char*)extents,sizeof (struct fiemap_extent)*num_extent);

    //printf("Start send to cosmos\n");
    DMA_Send("/dev/nvme0n1",buf_start,buf_size);

    gettimeofday(&end, 0);

    printf("Finish send to cosmos,return:%s\n",buf_start);

    free(buf_start);
    free(extents);

    //long seconds = end.tv_sec - begin.tv_sec;
    long microseconds = end.tv_usec - begin.tv_usec;
    //double elapsed = seconds + microseconds*1e-6;
    //printf("Time measured: %.3f seconds.\n", elapsed);
    printf("elapsed %ld us\n",microseconds);
    printf("get extend %ld us\n",getted.tv_usec - begin.tv_usec);
    printf("send extend %ld us\n",end.tv_usec - getted.tv_usec);

    return 0;
}